/**
 * 
 */
package furniture.items3d.bounds;

import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;

import furniture.items3d.Visitor;
import furniture.items3d.model.BoxPrimitive;
import furniture.items3d.model.CuboidPrimitive;
import furniture.items3d.model.LayedPrimitive;
import furniture.items3d.model.LayingModel;
import furniture.items3d.model.PipePrimitive;


/**
 * @author Grill Balazs (balage.g@gmail.com)
 *
 */
public class LayingBoundsVisitor implements Visitor {

	public Bounds3d bounds = null;
	
	public Bounds3d getBounds(){
		return bounds;
	}
	
	protected void addBounds(Bounds3d bounds){
		if (this.bounds == null) this.bounds = bounds;
		else{
			this.bounds = new Bounds3d(this.bounds,bounds);
		}
	}
	
	public void visit(LayingModel model){
		for (LayedPrimitive p : model.getPrimitives())
			p.accept(this);
	}
	
	
	public void visit(CuboidPrimitive cuboid){
		addBounds(new Bounds3d(new Vector3d(cuboid.startpoint), new Vector3d(cuboid.endpoint)));
	}
	
	public void visit(BoxPrimitive box){
		//we include at least 200m of of the box.
		Point3d p = box.point;
		
		Vector3d up = new Vector3d(0,1,0);
		Vector3d side = new Vector3d();
		side.cross(up, box.dir);
		
		up.scale(box.height*1.2/2);
		side.scale(box.width*1.2/2);
		
		Vector3d dir = new Vector3d(box.dir);
		dir.scale(100);//100mm to both direction
		
		Vector3d v1 = new Vector3d(p);
		v1.add(dir);
		v1.add(up);
		
		Vector3d v2 = new Vector3d(p);
		v2.sub(dir);
		v2.sub(up);
		
		Vector3d v3 = new Vector3d(p);
		v3.add(dir);
		v3.add(side);
		
		Vector3d v4 = new Vector3d(p);
		v4.sub(dir);
		v4.sub(side);
		
		addBounds(new Bounds3d(v1,v2,v3,v4));
	}
	
	public void visit(PipePrimitive pipe){
		//we include at least 200m of a pipe.
		Point3d p = pipe.point;
		
		Vector3d up = new Vector3d(0,1,0);
		Vector3d side = new Vector3d();
		side.cross(up, pipe.dir);
		
		up.scale(pipe.outerDiameter*1.2/2);
		side.scale(pipe.outerDiameter*1.2/2);
		
		Vector3d dir = new Vector3d(pipe.dir);
		dir.scale(100);//100mm to both direction
		
		Vector3d v1 = new Vector3d(p);
		v1.add(dir);
		v1.add(up);
		
		Vector3d v2 = new Vector3d(p);
		v2.sub(dir);
		v2.sub(up);
		
		Vector3d v3 = new Vector3d(p);
		v3.add(dir);
		v3.add(side);
		
		Vector3d v4 = new Vector3d(p);
		v4.sub(dir);
		v4.sub(side);
		
		addBounds(new Bounds3d(v1,v2,v3,v4));
	}
	
	
}
